---
title: 'Tutorial: Create an Astro Component'
description: 'Learn how to create your first Astro component.'
pubDate: 'Jul 02 2022'
heroImage: '../../assets/images/placeholder-hero.jpg'
category: 'Category 1'
tags: ['JavaScript', 'css', 'HTML5', 'GitHub']
---

**If you know HTML, you already know enough to write your first Astro component.**

Astro component syntax is a superset of HTML. The syntax was [designed to feel familiar to anyone with experience writing HTML or JSX](#differences-between-astro-and-jsx), and adds support for including components and JavaScript expressions.

## JSX-like Expressions

You can define local JavaScript variables inside of the frontmatter component script between the two code fences (`---`) of an Astro component. You can then inject these variables into the component's HTML template using JSX-like expressions!

:::note[dynamic vs reactive]
Using this approach, you can include **dynamic** values that are calculated in the frontmatter. But once included, these values are not **reactive** and will never change. Astro components are templates that only run once, during the rendering step.

See below for more examples of [differences between Astro and JSX](#differences-between-astro-and-jsx).
:::

### Variables

Local variables can be added into the HTML using the curly braces syntax:

```astro
---
const name = 'Astro'
---

<div>
	<h1>Hello {name}!</h1>
	<!-- Outputs <h1>Hello Astro!</h1> -->
</div>
```

### Dynamic Attributes

Local variables can be used in curly braces to pass attribute values to both HTML elements and components:

```astro title="src/components/DynamicAttributes.astro" "{name}" "${name}"
---
const name = 'Astro'
---

<h1 class={name}>Attribute expressions are supported</h1>

<MyComponent templateLiteralNameAttribute={`MyNameIs${name}`} />
```

:::caution
HTML attributes will be converted to strings, so it is not possible to pass functions and objects to HTML elements.
For example, you can't assign an event handler to an HTML element in an Astro component:

```astro
---
// dont-do-this.astro
function handleClick() {
	console.log('button clicked!')
}
---

<!-- ❌ This doesn't work! ❌ -->
<button onClick={handleClick}>Nothing will happen when you click me!</button>
```

Instead, use a client-side script to add the event handler, like you would in vanilla JavaScript:

```astro
---
// do-this-instead.astro
---

<button id='button'>Click Me</button>
<script>
	function handleClick() {
		console.log('button clicked!')
	}
	document.getElementById('button').addEventListener('click', handleClick)
</script>
```
